///**
// * Copyright 2010 the original author or authors.
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//package org.I0Itec.zkclient;
//
//import java.io.File;
//
//import java.io.IOException;
//import java.net.InetSocketAddress;
//import java.util.Arrays;
//
//import javax.annotation.PostConstruct;
//import javax.annotation.PreDestroy;
//
//import org.I0Itec.zkclient.exception.ZkException;
//import org.I0Itec.zkclient.exception.ZkInterruptedException;
//import org.apache.log4j.Logger;
//import org.apache.zookeeper.server.NIOServerCnxn;
//import org.apache.zookeeper.server.ZooKeeperServer;
//import org.apache.zookeeper.server.NIOServerCnxn.Factory;
//
//public class ZkServer {
//
//    private final static Logger LOG = Logger.getLogger(ZkServer.class);
//
//    public static final int DEFAULT_PORT = 2181;
//    public static final int DEFAULT_TICK_TIME = 5000;
//    public static final int DEFAULT_MIN_SESSION_TIMEOUT = 2 * DEFAULT_TICK_TIME;
//
//    private String _dataDir;
//    private String _logDir;
//
//    private IDefaultNameSpace _defaultNameSpace;
//
//    private ZooKeeperServer _zk;
//    private Factory _nioFactory;
//    private ZkClient _zkClient;
//    private int _port;
//    private int _tickTime;
//    private int _minSessionTimeout;
//
//    public ZkServer(String dataDir, String logDir, IDefaultNameSpace defaultNameSpace) {
//        this(dataDir, logDir, defaultNameSpace, DEFAULT_PORT);
//    }
//
//    public ZkServer(String dataDir, String logDir, IDefaultNameSpace defaultNameSpace, int port) {
//        this(dataDir, logDir, defaultNameSpace, port, DEFAULT_TICK_TIME);
//    }
//   public ZkServer(String dataDir, String logDir, IDefaultNameSpace defaultNameSpace, int port, int tickTime) {
//      this(dataDir, logDir, defaultNameSpace, port, tickTime, DEFAULT_MIN_SESSION_TIMEOUT);
//   }
//
//    public ZkServer(String dataDir, String logDir, IDefaultNameSpace defaultNameSpace, int port, int tickTime, int minSessionTimeout) {
//        _dataDir = dataDir;
//        _logDir = logDir;
//        _defaultNameSpace = defaultNameSpace;
//        _port = port;
//        _tickTime = tickTime;
//       _minSessionTimeout = minSessionTimeout;
//    }
//
//    public int getPort() {
//        return _port;
//    }
//
//    @PostConstruct
//    public void start() {
//        final String[] localHostNames = NetworkUtil.getLocalHostNames();
//        String names = "";
//        for (int i = 0; i < localHostNames.length; i++) {
//            final String name = localHostNames[i];
//            names += " " + name;
//            if (i + 1 != localHostNames.length) {
//                names += ",";
//            }
//        }
//        LOG.info("Starting ZkServer on: [" + names + "] port " + _port + "...");
//        startZooKeeperServer();
//        _zkClient = new ZkClient("localhost:" + _port, 10000);
//        _defaultNameSpace.createDefaultNameSpace(_zkClient);
//    }
//
//    private void startZooKeeperServer() {
//        final String[] localhostHostNames = NetworkUtil.getLocalHostNames();
//        final String servers = "localhost:" + _port;
//        // check if this server needs to start a _client server.
//        int pos = -1;
//        LOG.debug("check if hostNames " + servers + " is in list: " + Arrays.asList(localhostHostNames));
//        if ((pos = NetworkUtil.hostNamesInList(servers, localhostHostNames)) != -1) {
//            // yes this server needs to start a zookeeper server
//            final String[] hosts = servers.split(",");
//            final String[] hostSplitted = hosts[pos].split(":");
//            int port = _port;
//            if (hostSplitted.length > 1) {
//                port = Integer.parseInt(hostSplitted[1]);
//            }
//            // check if this machine is already something running..
//            if (NetworkUtil.isPortFree(port)) {
//                final File dataDir = new File(_dataDir);
//                final File dataLogDir = new File(_logDir);
//                dataDir.mkdirs();
//                dataLogDir.mkdirs();
//
//                if (hosts.length > 1) {
//                    // multiple zk servers
//                    LOG.info("Start distributed zookeeper server...");
//                    throw new IllegalArgumentException("Unable to start distributed zookeeper server");
//                }
//                // single zk server
//                LOG.info("Start single zookeeper server...");
//                LOG.info("data dir: " + dataDir.getAbsolutePath());
//                LOG.info("data log dir: " + dataLogDir.getAbsolutePath());
//                startSingleZkServer(_tickTime, dataDir, dataLogDir, port);
//            } else {
//                throw new IllegalStateException("Zookeeper port " + port + " was already in use. Running in single machine mode?");
//            }
//        }
//    }
//
//    private void startSingleZkServer(final int tickTime, final File dataDir, final File dataLogDir, final int port) {
//        try {
//            _zk = new ZooKeeperServer(dataDir, dataLogDir, tickTime);
//           _zk.setMinSessionTimeout(_minSessionTimeout);
//            _nioFactory = new NIOServerCnxn.Factory(new InetSocketAddress(port));
//            _nioFactory.startup(_zk);
//        } catch (IOException e) {
//            throw new ZkException("Unable to start single ZooKeeper server.", e);
//        } catch (InterruptedException e) {
//            throw new ZkInterruptedException(e);
//        }
//    }
//
//    @PreDestroy
//    public void shutdown() {
//        LOG.info("Shutting down ZkServer...");
//        try {
//            _zkClient.close();
//        } catch (ZkException e) {
//            LOG.warn("Error on closing zkclient: " + e.getClass().getName());
//        }
//        if (_nioFactory != null) {
//            _nioFactory.shutdown();
//            try {
//                _nioFactory.join();
//            } catch (InterruptedException e) {
//                Thread.currentThread().interrupt();
//            }
//            _nioFactory = null;
//        }
//        if (_zk != null) {
//            _zk.shutdown();
//            _zk = null;
//        }
//        LOG.info("Shutting down ZkServer...done");
//    }
//
//    public ZkClient getZkClient() {
//        return _zkClient;
//    }
//}
